/**
 * validate input
 * 结构:
 * <div id=''>
 * 		<ul>
 * 			<li><lable>
 * 				<span></span>
 * 				<span>
 * 					<input type='text' validate='require|email|number|int|length[n,m]|regex' />
 * 				</span>
 * 				<span class='validate-result' validate-msg=''></span>
 * 			</lable></li>
 * 		</ul>
 * </div>
 * @param
 * options = {
 * 		successClass: 'validate-success',
		errorClass: 'validate-error'		
 * }
 * @author  tanggf
 */
(function($){
	$.fn.validate = function(options){
		var opts = $.extend({
			successClass: 'validate-success',
			errorClass: 'validate-error',
			beforeValidate: function(){return true;}
		}, options);
		
		return this.each(function(){			
			_get_validte(this, opts);			
		});
	};
	
	$.extend({
		validate: function($ele, options){			
			var ele = $ele[0];
			var opts = _validate_opts(options);
			return _get_validte(ele, opts);
		}
	});
	
	function _validate_opts(options){
		return $.extend({
			successClass: 'validate-success',
			errorClass: 'validate-error'
		}, options);
	}
	
	function _get_validte(ele, options){
		var $this = $(ele);
		var vae = $this.data("_validate_");
		if( ! vae){
			vae = new _ValidatE_(ele, options);
			$this.data("_validate_", vae);
		}
		return vae;
	}
	
	function _ValidatE_(ele, options){
		this.$ele = $(ele);
		this.options = options;	
		this._init_();
	}
	
	_ValidatE_.prototype = {
		_init_: function(){
			var self = this;
			this.$inputs = $("ul > li span > input[type='text']", this.$ele);
			this.inputs = [];
			this.msgs = [];
			this.$inputs.each(function(){
				var $this = $(this);
				var $msg = $this.parent().siblings("span.validate-result");
				self.inputs.push($this);
				self.msgs.push($msg);
				$this.blur(function(){
					if(self.options.beforeValidate()){
						self._validate_($this, $msg);
					}					
				});				
			});			
		},
		
		validate: function(){
			var valid = true;
			for ( var i = 0; i < this.inputs.length; i++) {
				var $this = this.inputs[i];
				var $msg = this.msgs[i];
				if( ! this._validate_($this, $msg)){
					valid = false;
				}
			}
			return valid;
		},
		
		_validate_: function($this, $msg){
			var validate = $this.attr("validate");
			if( ! validate) return true;
			
			var value = $.trim($this.val());
			var valid = false;
			var v0 = null;
			var v1 = null;			
			if(validate == 'require'){				
				if(value){
					valid = true;
				}
			}else if(validate == 'email'){
				if(utils.isEmail(value)){
					valid = true;
				}
			}else if(validate == 'number'){
				if(utils.isNumber(value)){
					valid = true;
				}
				
			}else if(validate == 'int'){
				if(utils.isInt(value)){
					valid = true;
				}
			}else if(/^length\[(\d*),(\d+)\]$/.test(validate)){
				var s1 = parseInt(RegExp.$1) || 0;
				var s2 = parseInt(RegExp.$2) || 0;
				value = parseInt(value) || 0;
				if(s2 > s1){
					if(value < s1 || value > s2){
						valid = true;
						v0 = s1;
						v1 = s2;
					}
				}
			}else{
				//regex				
				var rex = new RegExp(validate);
				if(rex.test(value)){
					valid = true;
				}
			}
			
			if(valid){
				this._success_($this, $msg);
			}else{
				this._error_($this, $msg, v0, v1);
			}
			
			return valid;
		},
		
		_error_: function($this, $msg, v0, v1){
			var error = $msg.attr("error");
			if(error){
				if(v0){
					error = error.replace("{0}", v0);
				}
				if(v1){
					error = error.replace("{1}", v1);
				}				
			}
			$msg.addClass(this.options.errorClass).removeClass(this.options.successClass);			
			$msg.html(error);
		},
		
		_success_: function($this, $msg){
			$msg.removeClass(this.options.errorClass).addClass(this.options.successClass);	
			var success = $msg.attr("success") || "&nbsp;";			
			$msg.html(success);
		}
	};
})(jQuery);